package com.greendeliver.activities.base;

import java.io.Serializable;
import java.lang.Thread.UncaughtExceptionHandler;

import android.app.ListActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

import com.greendeliver.activities.ErrorActivity;

/** 
 * Activité de base. Cette classe ne peut être instanciée : elle contient des
 * méthodes communes pour les activités composant l'application.
 * 
 * @author Cyril Schumacher <cyril.dot.schumacher@gmail.com>
 * @see java.lang.Thread.UncaughtExceptionHandler
 */
public abstract class BaseListActivity extends ListActivity {
	/**
	 * Gestion des exceptions non attrapées.
	 * 
	 * @author Cyril Schumacher <cyril.dot.schumacher@gmail.com>
	 * @see android.app.Activity
	 */
	private class CustomExceptionHandler implements UncaughtExceptionHandler {
		/**
		 * Appelé lors une exception non interceptée survient.
		 * 
		 * @param arg0
		 *            Thread où l'exception est survenue.
		 * @param arg1
		 *            Exception survenue.
		 */
		@Override
		public void uncaughtException( Thread arg0, Throwable arg1 ) {
			Log.d( "uncaughtException", "An uncaught exception occurred : "
					+ arg1.getClass().getName() );

			// Navigue vers la vue affichant l'erreur.
			// On assigne des drapeaux pour effacer la pile des activités, cela
			// évite que l'utilisateur retourne sur les activités précédentes.
			navigateToActivity(
					ErrorActivity.class,
					( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK ), arg1 );

			// Termine l'activité actuelle.
			System.exit( RESULT_OK );
		}
	}

	/**
	 * Constructeur.
	 */
	protected BaseListActivity() {
		Log.d( "BaseListActivity", "Initializes the class" );
		Log.d( "BaseListActivity",
				"Class initialization for the management of uncaught exceptions" );
		Thread.setDefaultUncaughtExceptionHandler( new CustomExceptionHandler() );
	}

	/**
	 * Navigue vers une autre activity.
	 * 
	 * @param activity
	 *            Activité.
	 * @see com.greendeliver.activitie.BaseActivity#navigateToActivity(Class<?>,
	 *      List<Integer>)
	 * @return TRUE si la navigation a eu lieue, FALSE sinon.
	 */
	protected Boolean navigateToActivity( Class<?> activity ) {
		return navigateToActivity( activity, null, null );
	}

	/**
	 * Navigue vers une autre activity.
	 * 
	 * @param activity
	 *            Activité.
	 * @param flags
	 *            Drapeaux.
	 * @return TRUE si la navigation a eu lieue, FALSE sinon.
	 */
	protected Boolean navigateToActivity( Class<?> activity, Integer flags ) {
		return navigateToActivity( activity, flags, null );
	}

	/**
	 * Navigue vers une autre activity.
	 * 
	 * @param activity
	 *            Activité.
	 * @param flags
	 *            Drapeaux.
	 * @param data
	 *            Données.
	 * @return TRUE si la navigation a eu lieue, FALSE sinon.
	 */
	protected Boolean navigateToActivity( Class<?> activity, Integer flags,
			Serializable data ) {
		try {
			Log.d( "navigateToActivity", "Navigating to: " + activity.getName() );

			// Créer une instance de la classe "Intent" pour effectuer une
			// navigation.
			Intent intent = new Intent( this, activity );

			// Ajoute les drapeaux.
			if ( flags != null ) {
				Log.d( "navigateToActivity", "Flag: " + flags );
				intent.addFlags( flags );
			}

			// Ajoute les données.
			// La méthode "IsEmpty()" n'a pu être utilisée : elle requiert l'API
			// 9.
			if ( data != null ) {
				Log.d( "navigateToActivity", "Data: " + data );
				intent.putExtra( Intent.EXTRA_TEXT, data );
			}

			// Démarre la navigation.
			startActivity( intent );
			return true;
		} catch ( ActivityNotFoundException e ) {
			e.printStackTrace();

			// La méthode "startActivity" peut provoquer cette exception dans le
			// cas où l'activité n'existe pas.
			return false;
		}
	}

	/**
	 * Définit l'état du plein écran de la vue.
	 */
	protected void setFullscreen() {
		Log.d( "setFullscreen", "Display full screen view" );

		// Masque la barre de titre de l'activit�.
		requestWindowFeature( Window.FEATURE_NO_TITLE );
		// Met la vue en plein-�cran.
		getWindow().setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN );
	}
}
